package com.atguigu.gmall.order.listener;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.atguigu.gmall.common.config.mq.MqService;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.order.biz.OrderBizService;
import com.atguigu.gmall.order.entity.OrderInfo;
import com.atguigu.gmall.order.entity.PaymentInfo;
import com.atguigu.gmall.order.service.OrderInfoService;
import com.atguigu.gmall.order.service.PaymentInfoService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

@Service
@Slf4j
public class OrderPayedListener {
    @Autowired
    OrderBizService orderBizService;

    @Autowired
    OrderInfoService orderInfoService;

    @Autowired
    MqService mqService;

    @Autowired
    PaymentInfoService paymentInfoService;

    @RabbitListener(queues = MqConst.ORDER_PAYED_QUEUE)
    public void listen(Message message, Channel channel) throws IOException {
        long tag = message.getMessageProperties().getDeliveryTag();

        String messJson = new String(message.getBody());
        Map<String, String> stringStringMap = JSON.parseObject(messJson, new TypeReference<Map<String, String>>(){});
        log.info("修改订单状态为已支付：");
        //1.订单唯一对外交易号
        String out_trade_no = stringStringMap.get("out_trade_no");
        String[] split = out_trade_no.split("-");
        //2.用户Id
        Long userId = Long.valueOf(split[split.length - 1]);
        try {
            //根据唯一的对外交易号和用户Id修改订单为已支付状态

            orderBizService.payedOrder(out_trade_no,userId);

            //保存此次支付的回调数据信息：
            PaymentInfo info = preparePaymentInfo(messJson,stringStringMap,out_trade_no,userId);
            boolean save = paymentInfoService.save(info);
            log.info("订单{}，保存{}",out_trade_no,save);

            channel.basicAck(tag,false);
        } catch (Exception e) {
            //失败的话重试4次
            mqService.retry(channel,tag,messJson,4);
            throw new RuntimeException(e);
        }

    }

    private PaymentInfo preparePaymentInfo(String json, Map<String, String> content, String out_trade_no, Long userId) {
        OrderInfo orderInfo = orderInfoService.lambdaQuery()
                .eq(OrderInfo::getUserId, userId)
                .eq(OrderInfo::getOutTradeNo, out_trade_no)
                .one();
        PaymentInfo info = new PaymentInfo();
        info.setUserId(userId);
        info.setOutTradeNo(out_trade_no);
        info.setOrderId(orderInfo.getId().toString());
        info.setPaymentType(orderInfo.getPaymentWay());
        String trade_no = content.get("trade_no");
        info.setTradeNo(trade_no);
        String total_amount = content.get("total_amount");
        info.setTotalAmount(new BigDecimal(total_amount));
        info.setSubject(content.get("subject"));
        info.setPaymentStatus(content.get("trade_status"));
        info.setCreateTime(new Date());
        info.setCallbackTime(new Date());
        info.setCallbackContent(json);
        return info;
    }
}
